package vlcjdemo;

import com.jtrustn.VideoClipser.VideoClipser;
import java.awt.BorderLayout;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class Hmi implements ImageList.RenderValues, MouseListener, ListSelectionListener, KeyListener {

    VideoClipser aVideoClipser;
    ImageList aImageList;
    ImageList aOutImageList;
    volatile ArrayList<MovieClip> aMovieList = new ArrayList<MovieClip>();
    volatile ArrayList<MovieClip> aOutMovieList = new ArrayList<MovieClip>();
    volatile String movieFile = "C:\\aa\\mov\\saved\\Anita_Blonde_-_orient_express.avi";
    FFprobeParser inFFprobeParser = new FFprobeParser();
    FFprobeParser outFFprobeParser = new FFprobeParser();
    String filename = File.separator + "jtn";
    JFileChooser fc = new JFileChooser(new File(filename));
    //OpenFileFilter openFileFilter = new OpenFileFilter();
    volatile String TITLE = "Mp4MovieCreator";
    volatile int clipcount = 0;
    String STOPJOB = "No running task";

    /**
     * Creates new form ${name}
     */
    public Hmi(VideoClipser lVideoClipser) {
        aVideoClipser = lVideoClipser;
        aVideoClipser.setTitle(TITLE);
        jobStop();
        MovieClip[] items = aOutMovieList.toArray(new MovieClip[0]);
        aOutImageList = new ImageList((int) FFprobeParser.thumbNailWidth + 6, (int) 150 + 24, Hmi.this, items);
        JComponent aImageListView = aOutImageList.getView();
        aOutImageList.addMouseListener(this);
        aOutImageList.addKeyListener(this);
        aVideoClipser.outListPanel.add(aImageListView, BorderLayout.CENTER);
//        javax.swing.GroupLayout outPanelLayout = new javax.swing.GroupLayout(outPanel);
//        outPanel.setLayout(outPanelLayout);
//        outPanelLayout.setHorizontalGroup(
//                outPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(outPanelLayout.createSequentialGroup().addContainerGap().addComponent(aImageListView, javax.swing.GroupLayout.DEFAULT_SIZE, (int) inFFprobeParser.thumbNailWidth + 6 + 20, Short.MAX_VALUE).addContainerGap()));
//        outPanelLayout.setVerticalGroup(
//                outPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(outPanelLayout.createSequentialGroup().addContainerGap().addComponent(aImageListView, javax.swing.GroupLayout.DEFAULT_SIZE, 850, Short.MAX_VALUE).addContainerGap()));
//        outPanel.repaint();
    }

    public void createVideoButtonActionPerformed(java.awt.event.ActionEvent evt) {

        Runnable createMovie = new Runnable() {
            public void run() {
                String lmovieFile = movieFile;
//                FFprobeParser lFFprobeParser = aFFprobeParser;
                try {
//                    Object[] selected = aImageList.getSelectedObjects();
//                    aOutMovieList.clear();
//                    for (Object object : selected) {
//                        aOutMovieList.add((MovieClip) object);
//                    }
                    outFFprobeParser = new FFprobeParser();
                    outFFprobeParser.aMovieOutList = aOutMovieList;
                    int lAudioHz = Integer.parseInt(aVideoClipser.audioHzTextField.getText());
                    int lwidth = Integer.parseInt(aVideoClipser.widthTextField.getText());
                    int lheight = Integer.parseInt(aVideoClipser.heightTextField.getText());

                    outFFprobeParser.baselineProfile = aVideoClipser.oldTypeCheckBox.isSelected();
                    jobStart("Generating clips");
                    outFFprobeParser.writeFFMpegCmd(aVideoClipser.sizeCheckBox.isSelected(), lwidth, lheight,
                        aVideoClipser.audioHzCheckBox.isSelected(), lAudioHz,
                        aVideoClipser.aviCheckBox.isSelected(), clipcount);
                    if (!aVideoClipser.aviCheckBox.isSelected()) {
                        jobStart("Appending clips");
                        outFFprobeParser.writeAppendCmd(lmovieFile + clipcount + ".mp4");
                    }
                    clipcount++;
                    jobStop();
                } catch (Exception x) {
                    x.printStackTrace();
                }
            }
        };

        new Thread(createMovie).start();
    }

    public void importVideoButtonActionPerformed(String aMovieFile) {
        boolean runImport = false;
        if (aMovieFile != null) {
            movieFile = aMovieFile;
            runImport = true;
        } else {
            runImport = openFile();
        }

        if (runImport) {
            Runnable importMovie = new Runnable() {
                public void run() {
                    try {
                        jobStart("Parsing Movie");
                        final FFprobeParser aFFprobeParser = new FFprobeParser();
                        inFFprobeParser = aFFprobeParser;
                        aFFprobeParser.writeFFProbeCmd(movieFile);
                        jobStart("Creating thumbnails");
                        aFFprobeParser.writeJpgCmd();
                        aMovieList = aFFprobeParser.aMovieList;
                        jobStart("Loading thumbnails");

                        Runnable endImportMovie = new Runnable() {
                            public void run() {

                                MovieClip[] items = aMovieList.toArray(new MovieClip[0]);
                                aImageList = new ImageList((int) aFFprobeParser.thumbNailWidth + 6, (int) aFFprobeParser.thumbNailHeight + 24, Hmi.this, items);
                                JComponent aImageListView = aImageList.getView();
//                                aImageList.addMouseListener(Hmi.this);
                                aImageList.addListSelectionListener(Hmi.this);
                                aImageList.addKeyListener(Hmi.this);
                                aVideoClipser.inListPanel.removeAll();
                                aVideoClipser.inListPanel.add(aImageListView, BorderLayout.CENTER);
//        javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
//                                javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
//                                jPanel1.setLayout(jPanel1Layout);
//                                jPanel1Layout.setHorizontalGroup(
//                                        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup().addContainerGap().addComponent(aImageListView, javax.swing.GroupLayout.DEFAULT_SIZE, (int) aFFprobeParser.thumbNailWidth + 6 + 20, Short.MAX_VALUE).addContainerGap()));
//                                jPanel1Layout.setVerticalGroup(
//                                        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup().addContainerGap().addComponent(aImageListView, javax.swing.GroupLayout.DEFAULT_SIZE, 850, Short.MAX_VALUE).addContainerGap()));
//                                jPanel1.repaint();
                                jobStop();
                                clipcount = 0;
                            }
                        };
                        SwingUtilities.invokeLater(endImportMovie);
                    } catch (Exception x) {
                        x.printStackTrace();
                    }
                }
            };

            new Thread(importMovie).start();
        }
    }

    public void addOutButtonActionPerformed(java.awt.event.ActionEvent evt) {
        Object[] selected = aImageList.getSelectedObjects();
        Object[] outSelected = aOutImageList.getSelectedObjects();
        int idx = -1;
        if (outSelected.length > 0) {
            idx = aOutMovieList.indexOf(outSelected[outSelected.length - 1]);
        }

        ArrayList<MovieClip> aTempList = new ArrayList<MovieClip>();
        for (Object obj : selected) {
            aTempList.add((MovieClip) obj);
        }

        if (idx > -1) {
            aOutMovieList.addAll(idx, aTempList);
        } else {
            aOutMovieList.addAll(aTempList);
        }
        MovieClip[] items = aOutMovieList.toArray(new MovieClip[0]);
        aOutImageList.setItems(items);
        updateOutputTime(items);
    }

    public void removeOutButtonActionPerformed(java.awt.event.ActionEvent evt) {
        Object[] selected = aOutImageList.getSelectedObjects();
//                    aOutMovieList.clear();
        for (Object object : selected) {
            aOutMovieList.remove((MovieClip) object);
        }
        MovieClip[] items = aOutMovieList.toArray(new MovieClip[0]);
        aOutImageList.setItems(items);
        updateOutputTime(items);
    }

    public void clearOutButtonActionPerformed(java.awt.event.ActionEvent evt) {
        aOutMovieList.clear();
        MovieClip[] items = aOutMovieList.toArray(new MovieClip[0]);
        aOutImageList.setItems(items);
        updateOutputTime(items);
    }

    public void updateOutputTime(MovieClip[] items) {
        long totaltime = 0;
        for (MovieClip aMovieClip : items) {
            totaltime = totaltime + aMovieClip.durationDateL;
        }
        Date time = new Date(totaltime);
        String timeStr = outFFprobeParser.formatter.format(time);
        aVideoClipser.outputTimeLabel.setText(timeStr);
    }

    public void playButtonActionPerformed(java.awt.event.ActionEvent evt) {
        Runnable playMovie = new Runnable() {
            public void run() {
                try {
                    Object[] selected = aImageList.getSelectedObjects();
                    if (selected.length > 0) {
                        MovieClip aMovieClip = (MovieClip) selected[selected.length - 1];
                        inFFprobeParser.writePlayCmd(aMovieClip);
                    }
                } catch (Exception x) {
                    x.printStackTrace();
                }
            }
        };

        new Thread(playMovie).start();
    }

    public void playVideoButtonActionPerformed(java.awt.event.ActionEvent evt) {
        Runnable playMovie = new Runnable() {
            public void run() {
                try {
                    if (outFFprobeParser != null) {
                        outFFprobeParser.writePlayMovieCmd();
                    }
                } catch (Exception x) {
                    x.printStackTrace();
                }
            }
        };

        new Thread(playMovie).start();

    }

    public void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {
        inFFprobeParser.deleteFile(movieFile);
    }

    boolean openFile() {
        boolean ret = false;
        // Show dialog; this method does not return until dialog is closed
        fc.setMultiSelectionEnabled(false);
//	fc.setFileFilter(openFileFilter);
        fc.setDialogTitle("Open movie file .....");
//	if (aSciencePaperPanel.getCurrentFile() != null) {
//	  File f = new File(aSciencePaperPanel.getCurrentFile());
//	  fc.setSelectedFile(f);
//	}
        int result = fc.showOpenDialog(aVideoClipser);

        // Determine which button was clicked to close the dialog
        switch (result) {
            case JFileChooser.APPROVE_OPTION:
                // Approve (Open or Save) was clicked
                // Get the selected file
                File f = fc.getSelectedFile();
                movieFile = f.getPath();
                aVideoClipser.setTitle(TITLE + ": " + f.getPath());
                ret = true;
                break;
            case JFileChooser.CANCEL_OPTION:
                break;
            case JFileChooser.ERROR_OPTION:
                // The selection process did not complete successfully
                break;
        }
        return ret;
    }

    void jobStart(String message) {
        jobState(true, message);
    }

    void jobStop() {
        jobState(false, STOPJOB);
    }

    void jobState(final boolean running, final String message) {
        Runnable runjob = new Runnable() {
            public void run() {
                if (running) {
                    aVideoClipser.createVideoButton.setEnabled(false);
                    aVideoClipser.statusLabel.setBackground(new java.awt.Color(255, 153, 153));
                    aVideoClipser.statusLabel.setForeground(new java.awt.Color(255, 0, 0));
                    aVideoClipser.statusLabel.setText(message);
                } else {
                    aVideoClipser.createVideoButton.setEnabled(true);
                    aVideoClipser.statusLabel.setBackground(new java.awt.Color(153, 153, 255));
                    aVideoClipser.statusLabel.setForeground(new java.awt.Color(0, 0, 255));
                    aVideoClipser.statusLabel.setText(message);
                }
            }
        };
        SwingUtilities.invokeLater(runjob);
    }

    @Override
    public void requestCellImage(ImageList list, Object obj, int imageWidth, int imageHeight) {
        MovieClip aMovieClip = (MovieClip) obj;
        String theUrl = aMovieClip.jpgName;
        ImageIcon anotherIcon = new ImageIcon(theUrl);

//MediaTracker media = new MediaTracker(this);
//        Image image =
//                Toolkit.getDefaultToolkit().getImage(theUrl);
//        media.addImage(image, 0);
        try {
//            media.waitForID(0);
            int type = BufferedImage.TYPE_INT_RGB;
            BufferedImage bimage = new BufferedImage(imageWidth, imageHeight, type);
            Graphics g = bimage.createGraphics();
            Image aImage = anotherIcon.getImage();
            g.drawImage(aImage, 0, 0, null);
            g.dispose();

            list.putImage(obj, bimage);
            aImage.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    @Override
    public String getCellText(ImageList list, Object obj) {
        MovieClip aMovieClip = (MovieClip) obj;
        return "T:" + aMovieClip.time + ", D:" + aMovieClip.duration;
    }

    @Override
    public String getTooltipText(ImageList list, FontMetrics tooltipMetrics, Object obj) {
        MovieClip aMovieClip = (MovieClip) obj;
        return "Movie: " + aMovieClip.parrent.movieName;
    }

    void updateInputTime() {
        long totaltime = 0;
        Object[] selected = aImageList.getSelectedObjects();
        for (Object object : selected) {
            MovieClip aMovieClip = (MovieClip) object;
            totaltime = totaltime + aMovieClip.durationDateL;
        }
        Date time = new Date(totaltime);
        String timeStr = inFFprobeParser.formatter.format(time);
        aVideoClipser.inputTimeLabel.setText(timeStr);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.getSource() == aImageList.list) {
            updateInputTime();
        } else if (e.getSource() == aOutImageList.list) {
            long totaltime = 0;
            Object[] selected = aOutImageList.getSelectedObjects();
            for (Object object : selected) {
                MovieClip aMovieClip = (MovieClip) object;
                totaltime = totaltime + aMovieClip.durationDateL;
            }
            Date time = new Date(totaltime);
            String timeStr = outFFprobeParser.formatter.format(time);
            aVideoClipser.outputTimeLabel.setText(timeStr);
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    @Override
    public void valueChanged(ListSelectionEvent e) {
        if (!e.getValueIsAdjusting()) {
            updateInputTime();
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_DELETE) {
            removeOutButtonActionPerformed(null);
        }
        if (e.getKeyCode() == KeyEvent.VK_D) {
            removeOutButtonActionPerformed(null);
        }
        if (e.getKeyCode() == KeyEvent.VK_INSERT) {
            addOutButtonActionPerformed(null);
        }
        if (e.getKeyCode() == KeyEvent.VK_A) {
            addOutButtonActionPerformed(null);
        }
        if (e.getKeyCode() == KeyEvent.VK_C) {
            clearOutButtonActionPerformed(null);
        }
        if (e.getKeyCode() == KeyEvent.VK_P) {
            playButtonActionPerformed(null);
        }
        if (e.getKeyCode() == KeyEvent.VK_V) {
            playVideoButtonActionPerformed(null);
        }
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            createVideoButtonActionPerformed(null);
        }
        if (e.getKeyCode() == KeyEvent.VK_I) {
            importVideoButtonActionPerformed(null);
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }
}
